package com.wsch.client.process;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;

public class ProcessRunner {

	private static Map<String, ProcessRunner> ALLPROCESS = new HashMap<String, ProcessRunner>();

	private ProcessRunner() {
	}

	private PRunner run;
	private PState state;

	/**
	 * 创建过程运行器
	 * 
	 * @param run           运行逻辑
	 * @param maxProcessNum 最大进度值
	 * @param key           可以为空，为空时给任务分配随机key，否则以穿入key为准
	 * @return
	 */
	public static String creatInstance(PRunner run, int maxProcessNum, String key, Boolean isSyncronize) {

		if (isSyncronize == null) {
			isSyncronize = true;
		}

		if (StringUtils.isNotBlank(key) && ALLPROCESS.get(key) != null) {
			ALLPROCESS.get(key).run(isSyncronize);
			return key;
		}
		if (ALLPROCESS.size() > 100) {
			clear();
		}
		ProcessRunner runner = new ProcessRunner();
		runner.run = run;
		runner.state = new PState();
		runner.state.setMnum(maxProcessNum);
		if (StringUtils.isBlank(key)) {
			UUID uuid = UUID.randomUUID();
			key = uuid.toString();
		}
		ALLPROCESS.put(key, runner);
		runner.run(isSyncronize);
		return key;
	}

	/**
	 * 清理所有运行器
	 */
	private static void clear() {
		ALLPROCESS = new HashMap<String, ProcessRunner>();
	}

	public void run(Boolean isSyncronize) {
		if (!state.getState().equals(PState.StateEnum.running)) {
			Thread t = new Thread(new Runnable() {
				public void run() {
					state.setState(PState.StateEnum.running);
					state.setCnum(0);
					state.setMessage(null);
					try {
						run.run(state);
						state.setState(PState.StateEnum.finish);
					} catch (Exception e) {
						state.setState(PState.StateEnum.error);
						state.setMessage(e.getMessage());
					}
				}
			});
			if (isSyncronize) {
				t.start();
			} else {
				t.run();
			}
		}
	}

	public PState getState() {
		return state;
	}

	/**
	 * 获得一个存在的实例
	 * 
	 * @param skey
	 * @return
	 */
	public static ProcessRunner findInstance(String skey) {
		return ALLPROCESS.get(skey);
	}
}
